package com.the_last.task;

import com.the_last.constant.RedisKeyConstant;
import com.the_last.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 商品数据同步定时任务
 * 定时将Redis中的销量和库存数据同步到数据库
 * 
 * @author zhanghaifeng
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ProductSyncTask {
    
    private final ProductService productService;
    private final RedissonClient redissonClient;
    
    /**
     * 定时同步商品销量和库存数据到数据库
     * 每3小时执行一次（0点、3点、6点、9点、12点、15点、18点、21点）
     */
    @Scheduled(cron = "0 0 */3 * * ?")
    public void syncProductDataToDatabase() {
        log.info("开始执行商品数据同步任务");
        
        // 获取分布式锁，防止多个实例同时执行同步任务
        RLock lock = redissonClient.getLock(RedisKeyConstant.PRODUCT_SYNC_LOCK);
        
        try {
            // 尝试获取锁，等待5秒，锁持有时间30分钟
            boolean lockAcquired = lock.tryLock(5, 30 * 60, TimeUnit.SECONDS);
            
            if (!lockAcquired) {
                log.warn("获取商品数据同步锁失败，可能其他实例正在执行同步任务");
                return;
            }
            
            log.info("成功获取商品数据同步锁，开始同步数据");
            
            // 执行同步任务
            productService.syncProductDataFromRedisToDatabase();
            
            log.info("商品数据同步任务执行完成");
            
        } catch (InterruptedException e) {
            log.error("获取商品数据同步锁时被中断", e);
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.error("商品数据同步任务执行失败", e);
        } finally {
            // 释放锁
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
                log.info("释放商品数据同步锁");
            }
        }
    }
}